package com.lzyjkz.quick_auth.controller;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.lzyjkz.quick_auth.service.OAuthUserService;
import com.lzyjkz.quick_components.constant.RedisBucketConstant;
import com.lzyjkz.quick_components.entity.Response;
import com.lzyjkz.quick_components.service.TokenService;
import com.lzyjkz.quick_auth.util.OAuth2Util;
import com.lzyjkz.quick_components.constant.oauth.GiteeOAuthConstant;
import com.lzyjkz.quick_components.constant.oauth.GithubOAuthConstant;
import com.lzyjkz.quick_components.utils.RedisCache;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.concurrent.TimeUnit;

/*
 * @description: 第三方应用的回调controller
 */

@Controller
@RequiredArgsConstructor
@RequestMapping("/oauth")
@Slf4j
public class OauthController {

    private final OAuthUserService oAuthUserService;
    private final TokenService tokenService;
    private final RedisCache redisCache;

    @GetMapping("/github")
    @Transactional(rollbackFor = Throwable.class)
    public String github(HttpServletRequest request,String code, String state) throws NoSuchFieldException, IllegalAccessException {
        log.info(request.getMethod());
        // 获取accessToken请求响应
        String accessTokenResponse = OAuth2Util.getAccessToken(GithubOAuthConstant.class, code, state);

        // 提取accessToken
        String accessToken = accessTokenResponse.split("&")[0].split("=")[1];
        String scope = accessTokenResponse.split("&")[1].split("=")[1];
        String tokenType = accessTokenResponse.split("&")[2].split("=")[1];

        // 获取用户信息请求响应
        String userInfoResponse = OAuth2Util.getGitHubUserInfo(accessToken, scope, tokenType);

        // 解析用户信息
        JSONObject userInfo = JSONUtil.parseObj(userInfoResponse);

        if (!oAuthUserService.existUser(userInfo, "github")) {
            if (!oAuthUserService.saveUser(userInfo, "github")) {
                return "redirect:http://localhost:10923/500";
            }
        }
        UserDetails userDetails = oAuthUserService.getUserDetails(userInfo, "github");
        String userToken = tokenService.createUserToken(userDetails);
        redisCache.setCacheObject(RedisBucketConstant.OAUTH_LOGIN_CODE_BUCKET + code, userToken, 60, TimeUnit.SECONDS);
        return "redirect:http://localhost:10923/login?code=" + code;
    }

    @GetMapping("/gitee")
    @Transactional(rollbackFor = Throwable.class)
    public String gitee(String code, String state) throws NoSuchFieldException, IllegalAccessException {
        String accessTokenResponse = OAuth2Util.getAccessToken(GiteeOAuthConstant.class, code, state);
        JSONObject jsonObject = new JSONObject(accessTokenResponse);
        String accessToken = jsonObject.getStr("access_token");
        String scope = jsonObject.getStr("scope");
        String tokenType = jsonObject.getStr("token_type");
        String userInfoResponse = OAuth2Util.genericGetUserInfo(GiteeOAuthConstant.class, accessToken, scope, tokenType);
        JSONObject userInfo = JSONUtil.parseObj(userInfoResponse);
        System.out.println("userInfo = " + userInfo);
        if (!oAuthUserService.existUser(userInfo, "gitee")) {
            if (!oAuthUserService.saveUser(userInfo, "gitee")) {
                return "redirect:http://localhost:10923/500";
            }
        }
        UserDetails userDetails = oAuthUserService.getUserDetails(userInfo, "gitee");
        String userToken = tokenService.createUserToken(userDetails);
        redisCache.setCacheObject(RedisBucketConstant.OAUTH_LOGIN_CODE_BUCKET + code, userToken, 60, TimeUnit.SECONDS);
        return "redirect:http://localhost:10923/login?code=" + code;
    }

    @GetMapping("/getToken")
    @ResponseBody
    public Response<String> getToken(String code) {
        return Response.success(redisCache.getCacheObject(RedisBucketConstant.OAUTH_LOGIN_CODE_BUCKET + code));
    }
}
